home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright 1992 Eric R. Smith. All rights reserved.
- * Redistribution is permitted only if the distribution
- * is not for profit, and only if all documentation
- * (including, in particular, the file "copying")
- * is included in the distribution in unmodified form.
- * THIS PROGRAM COMES WITH ABSOLUTELY NO WARRANTY, NOT
- * EVEN THE IMPLIED WARRANTIES OF MERCHANTIBILITY OR
- * FITNESS FOR A PARTICULAR PURPOSE. USE AT YOUR OWN
- * RISK.
- */
- #include <stdlib.h>
- #include <string.h>
- #include "xgem.h"
- #include "toswin_w.h"
- #include "twdefs.h"
- #include "twproto.h"
-
- char *blank = "";
- FONTDESC *fontdesc;
-
- static void
- blankcopy(dest, src)
- char *dest, *src;
- {
- while (*dest && *src) {
- *dest++ = *src++;
- }
- while (*dest)
- *dest++ = ' ';
- }
-
- void
- init_fontdesc()
- {
- int i;
- int attrib[10];
- int charw, charh, boxw, boxh;
- char font_name[32];
- int orig_font, orig_size;
- int font_index;
- int prev_size, point_size;
-
- vqt_attributes(vdi_handle, attrib);
- orig_font = attrib[0];
- orig_size = attrib[7];
-
- fontdesc = malloc(gl_numfonts * sizeof(FONTDESC));
- for (i = 0; i < gl_numfonts; i++) {
- font_index = vqt_name(vdi_handle, i+1, font_name);
- if (font_name[BOXLEN]) { /* FSM font */
- fontdesc[i].isfsm = 1;
- } else {
- fontdesc[i].isfsm = 0;
- }
- font_name[BOXLEN] = 0;
- if (!strcmp(font_name, "6x6 system font"))
- strcpy(font_name, "System Font");
- strcpy(fontdesc[i].name, font_name);
- fontdesc[i].fontidx = font_index;
- fontdesc[i].points = 0L;
- vst_font(vdi_handle, font_index);
- point_size = 32;
- fontdesc[i].num_points = 0;
- for(;;) {
- prev_size = point_size - 1;
- point_size = vst_point(vdi_handle, prev_size,
- &charw, &charh, &boxw, &boxh);
- if (point_size > prev_size) break;
- fontdesc[i].points |= (1L << (long)point_size);
- fontdesc[i].num_points++;
- }
- }
- vst_font(vdi_handle, orig_font);
- vst_height(vdi_handle, orig_size, &charw, &charh, &boxw, &boxh);
- }
-
- #define NUMLINES 8
- #define FNTLIN FNTLIN1
- #define FNTLINLAST (FNTLIN+NUMLINES-1)
- #define SIZLIN SIZLIN1
- #define SIZLINLAST (SIZLIN+NUMLINES-1)
-
- void
- set_fontbox(off, maxfntoff, draw)
- int off, maxfntoff, draw;
- {
- int i;
- int n = FNTLIN;
- int fntoff = off;
-
- for (i = 0; i < gl_numfonts; i++) {
- if (off == 0) {
- blankcopy((char *)fontdial[n].ob_spec,
- fontdesc[i].name);
- fontdial[n].ob_flags |= TOUCHEXIT;
- fontdial[n].ob_state = NORMAL;
- if (++n > FNTLINLAST) break;
- } else
- --off;
- }
-
- while (n <= FNTLINLAST) {
- blankcopy((char *)fontdial[n].ob_spec, blank);
- fontdial[n].ob_flags &= ~TOUCHEXIT;
- fontdial[n].ob_state = NORMAL;
- n++;
- }
-
- if (gl_numfonts <= NUMLINES) {
- fontdial[FNTSLIDE].ob_y = 0;
- fontdial[FNTSLIDE].ob_height = fontdial[FNTSLIBX].ob_height;
- fontdial[FNTSLIDE].ob_flags &= ~TOUCHEXIT;
- fontdial[FNTSLIBX].ob_flags &= ~TOUCHEXIT;
- fontdial[FNTUPARR].ob_flags &= ~TOUCHEXIT;
- fontdial[FNTDNARR].ob_flags &= ~TOUCHEXIT;
- } else {
- i = (fontdial[FNTSLIBX].ob_height * NUMLINES) / gl_numfonts;
- if (i <= 0) i = 1;
- fontdial[FNTSLIDE].ob_y =
- (fontdial[FNTSLIBX].ob_height * fntoff) / gl_numfonts;
- fontdial[FNTSLIDE].ob_height = i;
- fontdial[FNTSLIDE].ob_flags |= TOUCHEXIT;
- fontdial[FNTSLIBX].ob_flags |= TOUCHEXIT;
- fontdial[FNTUPARR].ob_flags |= TOUCHEXIT;
- fontdial[FNTDNARR].ob_flags |= TOUCHEXIT;
- }
- if (draw) {
- objc_draw(fontdial, FNTSLIBX, 1, xdesk, ydesk, wdesk, hdesk);
- objc_draw(fontdial, FONTBOX, 1, xdesk, ydesk, wdesk, hdesk);
- }
- }
-
- static char *pointstr(d)
- int d;
- {
- static char foo[16];
- char *s;
-
- s = valdec(d);
- if (s[0] == '0') {
- s[0] = ' ';
- if (s[1] == '0') s[1] = ' ';
- }
- strcpy(foo, s);
- strcat(foo, " points");
- return foo;
- }
-
- void
- set_sizebox(f, off, draw)
- FONTDESC *f;
- int off, draw;
- {
- int i, j;
- int n = SIZLIN;
- int sizoff = off;
-
- for (j = 0; j < 32; j++) {
- if (f->points & (1L << (long)j)) {
- if (off == 0) {
- blankcopy((char *)fontdial[n].ob_spec,
- pointstr(j));
- fontdial[n].ob_flags |= TOUCHEXIT;
- fontdial[n].ob_state = NORMAL;
- if (++n > SIZLINLAST) break;
- } else {
- --off;
- }
- }
- }
- while (n <= SIZLINLAST) {
- blankcopy((char *)fontdial[n].ob_spec, blank);
- fontdial[n].ob_flags &= ~TOUCHEXIT;
- fontdial[n].ob_state = NORMAL;
- n++;
- }
- if (f->num_points <= NUMLINES) {
- fontdial[SIZSLIDE].ob_y = 0;
- fontdial[SIZSLIDE].ob_height = fontdial[SIZSLIBX].ob_height;
- fontdial[SIZSLIBX].ob_flags &= ~TOUCHEXIT;
- fontdial[SIZSLIDE].ob_flags &= ~TOUCHEXIT;
- fontdial[SIZUPARR].ob_flags &= ~TOUCHEXIT;
- fontdial[SIZDNARR].ob_flags &= ~TOUCHEXIT;
- } else {
- i = (fontdial[SIZSLIBX].ob_height * NUMLINES) / gl_numfonts;
- if (i <= 0) i = 1;
- fontdial[SIZSLIDE].ob_y =
- (fontdial[SIZSLIBX].ob_height * sizoff) / gl_numfonts;
- fontdial[SIZSLIDE].ob_height = i;
- fontdial[SIZSLIDE].ob_flags |= TOUCHEXIT;
- fontdial[SIZSLIBX].ob_flags |= TOUCHEXIT;
- fontdial[SIZUPARR].ob_flags |= TOUCHEXIT;
- fontdial[SIZDNARR].ob_flags |= TOUCHEXIT;
- }
- if (draw) {
- objc_draw(fontdial, SIZSLIBX, 1, xdesk, ydesk, wdesk, hdesk);
- objc_draw(fontdial, SIZEBOX, 1, xdesk, ydesk, wdesk, hdesk);
- }
- }
-
- /*
- * slide a box around, and return the new position for it
- */
-
- int
- slide(tree, box, slider, maxoff)
- OBJECT *tree;
- int box, slider, maxoff;
- {
- int totsiz = maxoff + NUMLINES;
- long r;
-
- r = graf_slidebox(tree, box, slider, 1);
- /* r is now scaled from 0-1000 */
- r = (totsiz * r) / 1000 - (NUMLINES/2);
- if (r < 0) r = 0;
- if (r > maxoff) r = maxoff;
- return r;
- }
-
- /*
- * respond to a click in the "page" area of a slider box
- */
-
- int
- page(tree, box, slider, off, maxoff)
- OBJECT *tree;
- int box, slider, off, maxoff;
- {
- int x1, y1, x2, y2;
- int x, y, dummy;
-
- graf_mkstate(&x, &y, &dummy, &dummy);
-
- /* mouse sanity check */
- objc_offset(tree, box, &x1, &y1);
- if (x < x1 || x > x + tree[box].ob_width || y < y1 ||
- y > y + tree[box].ob_height) return off;
-
- /* check first rectangle */
- objc_offset(tree, slider, &x2, &y2);
- if (y >= y1 && y < y2) { /* yes, it's a page up */
- off -= NUMLINES;
- if (off < 0) off = 0;
- return off;
- }
- /* OK, check second rectangle */
- y1 += tree[box].ob_height;
- y2 += tree[slider].ob_height;
- if (y > y2 && y <= y1) {
- off += NUMLINES;
- if (off > maxoff) off = maxoff;
- }
- return off;
- }
-
- #define update_sizebox() objc_draw(fontdial, SIZNMBOX, 3, x, y, w, h);
-
- int
- get_font(font, size)
- int *font, *size;
- {
- int i, x, y, w, h;
- int ret;
- int doubleclick;
- int oldfnt = -1;
- int fntoff, sizoff;
- int oldsiz = -1;
- FONTDESC *f;
- int maxfntoff, maxsizoff;
- char *sizestr;
- TEDINFO *ted;
-
- fntoff = sizoff = maxsizoff = 0;
-
- ted = (TEDINFO *)fontdial[SIZNMPTS].ob_spec;
- sizestr = (char *)ted->te_ptext;
-
- maxfntoff = gl_numfonts - NUMLINES;
-
- /* see if we can find the already existing font and size */
- f = 0;
- for (i = 0; i < gl_numfonts; i++) {
- if (fontdesc[i].fontidx == *font) {
- f = &fontdesc[i];
- break;
- }
- }
- if (f) {
- blankcopy((char *)fontdial[FNTNMSTR].ob_spec, f->name);
- maxsizoff = f->num_points - NUMLINES;
- set_sizebox(f, 0, 0);
- } else {
- blankcopy((char *)fontdial[FNTNMSTR].ob_spec, blank);
- for (i = SIZLIN; i <= SIZLINLAST; i++) {
- blankcopy((char *)fontdial[i].ob_spec, blank);
- fontdial[i].ob_flags &= ~TOUCHEXIT;
- }
- fontdial[SIZSLIDE].ob_height = fontdial[FNTSLIBX].ob_height;
- fontdial[SIZSLIDE].ob_flags &= ~TOUCHEXIT;
- fontdial[SIZUPARR].ob_flags &= ~TOUCHEXIT;
- fontdial[SIZDNARR].ob_flags &= ~TOUCHEXIT;
- }
-
- if (f && (f->points & (1L << (long)*size))) {
- char *s = pointstr(*size);
- sizestr[0] = s[1];
- sizestr[1] = s[2];
- } else {
- sizestr[0] = sizestr[1] = ' ';
- }
-
- form_center(fontdial, &x, &y, &w, &h);
- set_fontbox(fntoff, maxfntoff, 0);
-
- wind_update(1);
- form_dial(FMD_START, 0, 0, 32, 32, x, y, w, h);
- if (win_flourishes)
- form_dial(FMD_GROW, 0, 0, 32, 32, x, y, w, h);
- objc_draw(fontdial, 0, 5, x, y, w, h);
-
- for(;;) {
- doubleclick = 0;
- ret = form_do(fontdial, SIZNMPTS);
- if (ret & 0x8000) {
- doubleclick = 1;
- ret &= 0x7fff;
- }
- if (ret == FNTOK || ret == FNTCAN) {
- objc_change(fontdial, ret, 0, x, y, w, h, NONE, 0);
- break;
- }
- else if (ret >= FNTLIN && ret <= FNTLINLAST) {
- if (oldfnt >= 0) {
- objc_change(fontdial, oldfnt, 0, x, y, w, h,
- NONE, 1);
- }
- if (ret != oldfnt) {
- sizestr[0] = sizestr[1] = ' ';
- update_sizebox();
- }
- oldfnt = ret;
- objc_change(fontdial, ret, 0, x, y, w, h, SELECTED, 1);
- f = &fontdesc[ret-FNTLIN+fntoff];
- blankcopy((char *)fontdial[FNTNMSTR].ob_spec, f->name);
- objc_draw(fontdial, FNTNMBOX, 1, x, y, w, h);
- sizoff = 0; oldsiz = -1;
- maxsizoff = f->num_points - NUMLINES;
- set_sizebox(f, sizoff, 1);
- }
- else if (ret >= SIZLIN && ret <= SIZLINLAST) {
- if (oldsiz >= 0) {
- objc_change(fontdial, oldsiz, 0, x, y, w, h,
- NONE, 1);
- }
- oldsiz = ret;
- objc_change(fontdial, ret, 0, x, y, w, h, SELECTED, 1);
- sizestr[0] = ((char *)fontdial[ret].ob_spec)[1];
- sizestr[1] = ((char *)fontdial[ret].ob_spec)[2];
- update_sizebox();
- if (doubleclick) break;
- }
- else if (ret == FNTUPARR && fntoff > 0) {
- fntoff--;
- set_fontbox(fntoff, maxfntoff, 1);
- } else if (ret == FNTDNARR && fntoff < maxfntoff) {
- fntoff++;
- set_fontbox(fntoff, maxfntoff, 1);
- } else if (ret == SIZUPARR && sizoff > 0) {
- sizoff--;
- set_sizebox(f, sizoff, 1);
- } else if (ret == SIZDNARR && sizoff < maxsizoff) {
- sizoff++;
- set_sizebox(f, sizoff, 1);
- } else if (ret == FNTSLIDE) {
- fntoff = slide(fontdial, FNTSLIBX, FNTSLIDE, maxfntoff);
- set_fontbox(fntoff, maxfntoff, 1);
- } else if (ret == SIZSLIDE) {
- sizoff = slide(fontdial, SIZSLIBX, SIZSLIDE, maxsizoff);
- set_sizebox(f, sizoff, 1);
- } else if (ret == SIZSLIBX) {
- sizoff = page(fontdial, SIZSLIBX, SIZSLIDE, sizoff,
- maxsizoff);
- set_sizebox(f, sizoff, 1);
- } else if (ret == FNTSLIBX) {
- fntoff = page(fontdial, FNTSLIBX, FNTSLIDE, fntoff,
- maxfntoff);
- set_fontbox(fntoff, maxfntoff, 1);
- }
- }
- if (win_flourishes)
- form_dial(FMD_SHRINK, 0, 0, 32, 32, x, y, w, h);
- form_dial(FMD_FINISH, 0, 0, 32, 32, x, y, w, h);
- wind_update(0);
-
- if (ret == FNTCAN || !f)
- return FAIL;
-
- while (*sizestr == ' ') sizestr++;
- i = (*sizestr - '0'); sizestr++;
- if (i < 0 || i > 9) return FAIL;
- if (*sizestr >= '0' && *sizestr <= '9') {
- i = 10 * i + (*sizestr - '0');
- }
-
- *font = f->fontidx;
- *size = i;
-
- return OK;
- }
-